/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package io.renren.modules.project.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.PageList;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.RedisUtils;
import io.renren.modules.project.dao.BackendDao;
import io.renren.modules.project.dao.ModuleDao;
import io.renren.modules.project.entity.BackendEntity;
import io.renren.modules.project.entity.ModuleEntity;
import io.renren.modules.project.service.BackendService;
import io.renren.modules.project.service.ModuleService;
import io.renren.modules.systemconfig.dao.SysConfigServerDao;
import io.renren.modules.systemconfig.entity.SystemConfigServersEntity;
import io.renren.ssh.FileAttri;
import io.renren.ssh.SFTPClient;
import io.renren.ssh.SSHClient;
import io.renren.ssh.SshResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.convert.EntityWriter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 系统用户
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service("backendService")
public class BackendServiceImpl extends ServiceImpl<BackendDao, BackendEntity> implements BackendService {
	@Autowired
	private ModuleService moduleService;

	@Autowired
	private SysConfigServerDao serverMapper;

	@Autowired
	private RedisUtils redisUtils;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String key = (String)params.get("key");
		Long  current = Long.parseLong((String)params.get("page"));
		Long size = Long.parseLong((String)params.get("limit"));
		List<BackendEntity> records = this.baseMapper.selectEntityPage(key,size*(current-1),size*current);
		IPage<BackendEntity> page = new Page<>(current, size, this.baseMapper.selectRecordSize(key));
		page.setRecords(records);
		return new PageUtils(page);
	}

	@Override
	public PageUtils treeList(Map<String, Object> params) {
		String key = (String)params.get("key");
		Long  current = Long.parseLong((String)params.get("page"));
		Long size = Long.parseLong((String)params.get("limit"));
		List<BackendEntity> records = this.baseMapper.selectEntityPage(key,size*(current-1),size*current);
		IPage<BackendEntity> page = new Page<>(current, size, this.baseMapper.selectRecordSize(key));
		for(BackendEntity be:records){
			be.setModules(moduleService.list(new QueryWrapper<ModuleEntity>().eq("backend_id",be.getId())));
		}
		page.setRecords(records);
		return new PageUtils(page);
	}

	@Override
	public List<ModuleEntity> treeLog(long backendId) {
		List<ModuleEntity> modules = moduleService.selectModuleServerListByBackendId(backendId);
		HashMap<Long,SFTPClient> ServerId_SFTPClient = new HashMap<>();
		modules.stream().forEach(m ->{
			try{
				if(!ServerId_SFTPClient.containsKey(m.getServerId())) {
					ServerId_SFTPClient.put(m.getServerId(), new SFTPClient(m.getServer()));
				}
				List<FileAttri> info= ServerId_SFTPClient.get(m.getServerId()).lsLogs(m.getDeployPath());
				m.setLogs(info);
			}catch (Exception e){
				e.printStackTrace();
			}
		});
		ServerId_SFTPClient.values().stream().forEach(sftpClient -> {
			try {
				sftpClient.close();
			}catch (Exception e){
				e.printStackTrace();
			}

		});
		return modules;
	}

	@Override
	public void clearLog(Long serverId, String logPath) throws Exception{
		SystemConfigServersEntity server = serverMapper.selectById(serverId);
		if(server!=null){
			SSHClient client =new SSHClient(server);
			client.exec("echo '' >"+logPath +" \n");
			client.close();
		}
	}

	@Override
	public PageUtils showLogContent(Long serverId, String logPath,Long page,Long limit,boolean toEnd) {
		SystemConfigServersEntity server = serverMapper.selectById(serverId);
		if(page==null&&page<1){
			page=1l;
		}
		if(limit==null){
			limit=20l;
		}
		if(server!=null){
			try{
				SSHClient client =new SSHClient(server);

				StringBuffer sb = client.exec("wc -l "+ logPath);
				String[] result = sb.toString().split("\n");
				if(result.length>0){
					String [] resultList = result[0].trim().split("\\s+");
					if(resultList.length>0){
						long tempTotal = Long.parseLong(resultList[0]);
						if(toEnd){
							page=tempTotal/limit-1;
						}
						System.out.println("sed -n '"+(page*limit)+","+((page+1)*limit)+"p' "+logPath);
						sb = client.exec("sed -n '"+(page*limit)+","+((page+1)*limit)+"p' "+logPath);
						client.close();
						IPage<String> results = new Page<>(page, limit, tempTotal);
						results.setRecords(Arrays.asList(sb.toString().split("\n")));
						return new PageUtils(results);
					}
				}
			}catch (Exception e){
				e.printStackTrace();
			}
		}
		return null;
	}

	@Override
	public BackendEntity getBackendTreeByProjectId(Long id) {
		BackendEntity be = this.baseMapper.selectOne(new QueryWrapper<BackendEntity>().eq("project_id",id));
		if(be!=null){
			List<ModuleEntity> modules = moduleService.list(new QueryWrapper<ModuleEntity>().eq("backend_id",be.getId()));
			modules.stream().forEach(s -> {
				System.out.println("module-"+s.getId()+":"+redisUtils.get("module-"+s.getId()));
				s.setRuntimeStatus(redisUtils.get("module-"+s.getId()));
			});
			be.setModules(modules);
		}
		return be;
	}

	@Override
	public BackendEntity queryByKey(String key) {
		return baseMapper.queryByKey(key);
	}

	@Override
	@Transactional
	public void saveEntity(BackendEntity entity) {
		this.baseMapper.insert(entity);
	}

	@Override
	@Transactional
	public void update(BackendEntity user) {
		this.updateById(user);
	}

	@Override
	public void deleteBatch(Long[] userId) {
		this.removeByIds(Arrays.asList(userId));
	}



}